/**
 * 20.局部变量&全局变量 https://www.bilibili.com/video/BV1vs411n7TH?p=91
 *
 * 全局变量: 存储在"数据区", 不是存储在"栈区".
 *          不可以"重复定义"全局变量(不同文件的全局变量不可重名), 否则编译报错!!!
 *
 * 局部变量: 存储在"栈区"
 *
 *
 * 数据类型        作用域     extern外部引用    生命周期          存储位置   不同方法(是否可重复定义)  不同文件    备注
 * 局部变量       函数内部         ✘        局部变量创建->函数结束  栈区         ✔                 ✔
 * 全局变量       项目all文件      ✔        程序创建->销毁        数据区                          ✘(不可重名) 重名编译报错!
 * static局部变量 函数内部         ✘        程序创建->销毁        数据区        ✔                 ✔
 * static全局变量 定义所在文件中    ✘        程序创建->销毁        数据区                           ✔        相当于Java的private, 仅可在本文件中使用, 不能外部 extern 引用!!!
 */
#include <stdio.h>

void data_store_location();

//1.声明 Global.c 中的 PI 全局变量
extern  float PI;
int main() {
    printf("PI = %f\n", PI);

    //2.数据存储位置
    data_store_location();
    return 0;
}

/**
 * 数据存储位置: https://www.bilibili.com/video/BV1vs411n7TH?p=94
 * 栈区  : (局部)变量, (局部)常量, (局部)字符串常量, (局部)数组, (局部)指针      //仅有  : 局部(不能包含static)
 * 数据区: 未初始化(全局)常量, 未初始化[静态](全局)变量, 未初始化(静态)局部变量    //只要有: 全局&静态
 *          初始化[静态](全局)变量,  初始化(静态)局部变量
 */
//未初始化 全局常量
const int a1_store;
//初始化 全局常量
const int b1_store = 10;
//未初始化 全局变量
int c1_store;
//初始化 全局变量
int d1_store = 10;
//未初始化 静态 全局变量
static int e1_store;
//初始化 静态 全局变量
static int f1_store = 10;
void data_store_location() {
    //未初始化 局部常量
    const int a1;
    //初始化 局部常量
    const int b1 = 10;
    //未初始化 局部变量
    int c1;
    //初始化 局部变量
    int e1 = 10;
    //未初始化 静态 局部变量
    static int f1;
    //初始化 静态 局部变量
    static int g1 = 10;
    //字符串常量
    char *p1 = "Hello World!";
    //数组 局部变量
    int ar[] = {1, 2, 3};
    //指针
    int *pp = ar;
    printf("未初始化     全局常量: a1 = %p\n", &a1_store);//00406404
    printf("  初始化     全局常量: b1 = %p\n", &b1_store);//00404074
    printf("未初始化     全局变量: c1 = %p\n", &c1_store);//00406408
    printf("  初始化     全局变量: d1 = %p\n", &d1_store);//00403008
    printf("未初始化 静态 全局变量: e1 = %p\n", &e1_store);//00406034
    printf("  初始化 静态 全局变量: f1 = %p\n", &f1_store);//0040300C
    printf("未初始化     局部常量: a1 = %p\n", &a1);      //0061FEBC
    printf("  初始化     局部常量: b1 = %p\n", &b1);      //0061FEB8
    printf("未初始化     局部变量: c1 = %p\n", &c1);      //0061FEB4
    printf("  初始化     局部变量: e1 = %p\n", &e1);      //0061FEB0
    printf("未初始化 静态 局部变量: f1 = %p\n", &f1);      //00406038
    printf("  初始化 静态 局部变量: g1 = %p\n", &g1);      //00403010
    printf("字符串常量          : p1 = %p\n", &p1);       //0061FEAC
    printf("数组    局部变量 地址: ar = %p\n", &ar);       //0061FEA0
    printf("指针            变量: pp = %p\n", pp);       //0061FEA0
    printf("指针            地址: pp = %p\n", &pp);      //0061FE9C
}
